package org.jmh.gift.listener;

import cn.hutool.core.collection.CollectionUtil;
import org.jmh.gift.client.GiftClient;
import org.jmh.gift.client.PayClient;
import org.jmh.gift.constants.OrderConstants;
import org.jmh.gift.domain.OrderGift;
import org.jmh.gift.dto.PlaceOrderDTO;
import org.jmh.gift.service.IOrderGiftService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 订单超时未支付取消的消息监听
 */
@Component
@RocketMQMessageListener(topic = OrderConstants.ORDER_TIMEOUT_NOPAY_TOPIC,
                        consumerGroup = OrderConstants.ORDER_TIMEOUT_NOPAY_CONSUMER_GROUP)
public class OrderTimeoutNoPayMessageListener implements RocketMQListener<MessageExt> {

    @Autowired
    private IOrderGiftService orderGiftService;

    @Autowired
    private PayClient payClient;

    @Autowired
    private GiftClient giftClient;

    @Override
    public void onMessage(MessageExt message) {
        // 1 获取消息内容
        String string = new String(message.getBody());
        PlaceOrderDTO dto = JSONObject.parseObject(string, PlaceOrderDTO.class);
        String parentOrderNo = dto.getParentOrderNo();
        String uniPayOrderSn = dto.getUniPayOrderSn();
        Map<Long, Integer> skuInfos = dto.getSkuInfos();

        // 2 根据parentOrderNo查询订单状态
        List<OrderGift> orderGifts = orderGiftService.selectList(
                new EntityWrapper<OrderGift>()
                        .eq("parent_order_no", parentOrderNo)
                        .and()
                        .eq("status", 0));

        // 3 如果订单已支付，就不做处理
        // 4 如果订单状态=待支付，说明超过一定时间依然没有支付
        if(CollectionUtil.isNotEmpty(orderGifts)){
            // 4.1 将订单状态修改 = 超时取消 - 订单服务
            for (OrderGift orderGift : orderGifts) {
                orderGift.setStatus(-1);
                orderGift.setUpdateTime(new Date());
            }
            orderGiftService.updateBatchById(orderGifts);

            // 4.2 将支付单状态修改 = 取消  - 支付服务
            payClient.cancelPayOrder(uniPayOrderSn);

            // 4.3 扣减锁定库存 - 礼物服务
            giftClient.subLockStock(skuInfos);
        }

        // 以上三个服务的数据要保持一致，分布式事务
        // 分布式事务的解决方案： 2pc(并发不高，子事务执行周期短  seata)
        // tcc 可靠消息最终一致性(并发高或者子事务执行周期长)  最大努力通知
    }
}
